package org.ccay.validator.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import org.ccay.validator.IValidatorContext;
import org.ccay.validator.ValidationMessage;
import com.opensymphony.xwork2.LocaleProvider;
import com.opensymphony.xwork2.TextProvider;
import com.opensymphony.xwork2.TextProviderFactory;
import com.opensymphony.xwork2.ValidationAware;
import com.opensymphony.xwork2.validator.DelegatingValidatorContext;

/**
 * DefaultValidatorContext
 * 
 * 验证上下文
 * 
 * 在xwork的默认验证上下文中，加入验证目标对象。 此对象将在DefaultValidatorManager.validate()中使用。
 * 
 * @see org.ccay.validator.impl.DefaultValidatorManager#validateObject
 *      object, String context, ValidatorContext validatorContext, String
 *      method)
 * 
 * @author chaowangbang
 * 
 */
public class DefaultValidatorContext extends DelegatingValidatorContext implements IValidatorContext {

	/** 上下文参数 */
	private Map<String, Object> validatorContext = new HashMap<String, Object>();
	
	/** Action error message list **/
	private List<ValidationMessage> actionErrors = new ArrayList<ValidationMessage>();
	
	/** field error message list **/
	private List<ValidationMessage> fieldErrors = new ArrayList<ValidationMessage>();

	/**
	 * Creates a new validation context given an object - usually an Action. The
	 * internal objects (validation aware instance and a locale and text
	 * provider) are created based on the given action.
	 * 
	 * @param object
	 *            the object to use for validation (usually an Action).
	 */
	public DefaultValidatorContext(ValidationAware validationAware, TextProvider textProvider,
            LocaleProvider localeProvider) {
		super(validationAware, textProvider, localeProvider);
	}

	@SuppressWarnings("unchecked")
	public <T> T getParam(String key, Class<T> requiredType) {
		Object bean = validatorContext.get(key);
		return (T) bean;
	}

	public void setParam(String key, Object value) {
		validatorContext.put(key, value);
	}
	
	public void addActionError(ValidationMessage message) {
		this.actionErrors.add(message);
	}
	
	public void addFieldError(ValidationMessage message) {
		this.fieldErrors.add(message);
	}
	
	public List<ValidationMessage> getActionErrorsWithRowInfo() {
		return this.actionErrors;
	}
	
	public List<ValidationMessage> getFieldErrorsWithRowInfo() {
		return this.fieldErrors;
	}

	@Override
	public boolean hasActionErrors() {
		return !this.actionErrors.isEmpty();
	}

	@Override
	public boolean hasErrors() {
		return hasActionErrors() || hasFieldErrors();
	}

	@Override
	public boolean hasFieldErrors() {
		return !this.fieldErrors.isEmpty();
	}

	public static class Builder {

		public DefaultValidatorContext build(Object object, ResourceBundle bundle) {
            LocaleProvider localeProvider = makeLocaleProvider(object);
			ValidationAware validationAware = makeValidationAware(object);
	        TextProvider textProvider = makeTextProvider(bundle, localeProvider);
	        return new DefaultValidatorContext(validationAware, textProvider, localeProvider);
		}
	}

	/**
	 * @param object
	 * @param localeProvider
	 * @return
	 */
	public static TextProvider makeTextProvider(ResourceBundle bundle, LocaleProvider localeProvider) {
		// the object argument passed through here will most probably be an
		// ActionSupport decendant which does
		// implements TextProvider.
		return new TextProviderFactory().createInstance(bundle, localeProvider);
	}

}
